#include <cstdio>
#include <algorithm>
#include <set>

int floor(int x, int y){
    if (x<0 && y<0){
        x = -x;
        y = -y;
    }

    int res = x/y;

    if (!(x % y))
        --res;
    
    return res;
}

int ceil(int x, int y){
    if (x<0 && y<0){
        x = -x;
        y = -y;
    }

    int res = x/y;

    ++res;
    
    return res;
}

struct car{
    int l, r;

    friend bool operator<(car a, car b){
        return a.r == b.r ? a.l < b.l : a.r < b.r;
    }

} c[100005];

int p[100005];

int s[1000005];

void solve(){
    int n, m, l, v1;
    scanf("%d %d %d %d", &n, &m, &l, &v1);

    for (int i=1; i<=n; ++i){
        int p, v0, a;
        scanf("%d %d %d", &p, &v0, &a);
        if (v0>v1 && a>=0)
            c[i] = {p, l};
        if (v0>v1 && a<0)
            c[i] = {p, std::min(p+floor(v1*v1-v0*v0, 2*a), l)};
        if (v0<=v1 && a<=0)
            c[i] = {l, 0};
        if (v0<=v1 && a>0)
            c[i] = {p+ceil(v1*v1-v0*v0, 2*a), l};
        // fprintf(stderr, "%d: %d %d %d: %d %d\n", p, v0, v1, a, c[i].l, c[i].r);
    }

    for (int i=0; i<=l; ++i)
        s[i] = 0;

    for (int i=1; i<=m; ++i){
        scanf("%d", p+i);
        s[p[i]] = 1;
    }

    for (int i=1; i<=l; ++i)
        s[i] += s[i-1];
    
    std::multiset<car> set;
    
    for (int i=1; i<=n; ++i){
        if (c[i].l <= c[i].r){
            if (s[c[i].r]-(c[i].l?s[c[i].l-1]:0) > 0){
                set.insert(c[i]);
            }
        }
    }

    int cnt = 0, pos = -1;

    for (car x:set){
        if (x.l > pos){
            ++cnt;
            pos = *(std::upper_bound(p+1, p+m+1, x.r)-1);
        }
    }

    printf("%d %d\n", set.size(), m-cnt);

    return;
}

int main(){
    freopen("detect.in" , "r", stdin );
    freopen("detect.out", "w", stdout);

    int t;
    scanf("%d", &t);

    while (t--)
        solve();

    return 0;
}

